/**************************************************START OF FILE*****************************************************/






/*------------------------------------------------------------------------------------------------------------------
Includes
*/

#include "stdint.h"
#include "stm32f0xx_hal.h"
#include "xBsp_Hcs301.h"

#include "xApp_GLB_Define.h"


/*------------------------------------------------------------------------------------------------------------------
Definitions
*/
#define GET_TIMERCOUNT() (TIM16->CNT)

/*------------------------------------------------------------------------------------------------------------------
Variables
*/

uint8_t WakeupEnable = 1;


//接收到的两个数据
uint32_t EncryPortion = 0;      
uint32_t EncryPortion_de = 0;
uint32_t FixedPortion = 0;
uint32_t FixedPortion_de = 0;

//标记接收的状态机
uint8_t HCS301_DecodeStep = 0;



//接收到的同步值（同步值一样时表示重发）
uint16_t Sync_Current = 0;  //当前
uint16_t Sync_Last = 0;     //上一次


//解密的秘钥 低字节在前(实际秘钥是0x0123456789ABCDEF)
uint8_t HCS301_Decryptkey[]={0XEF,0XCD,0XAB,0X89,0X67,0X45,0X23,0X01};
//加密解密数据
unsigned char source[4];



/*------------------------------------------------------------------------------------------------------------------
Code
*/
void WriteBit(uint8_t bit , uint8_t value);
void Test_DECRYPT(uint32_t data);




/*
*********************************************************************************************************************

@ Brief  : 接收引脚边沿触发

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-03 18:53

*********************************************************************************************************************
*/
void xSYS_HCS301_IRQHandler(void)
{
	static uint16_t CurrentTimeValue;		//当前定时器的值
	static uint16_t LastTimeValue;			//上次定时器的值
	static uint16_t DetaTimeValue;			//两次进入函数的时间差
	static uint32_t PwmCount;				//前导部分PWM的计数值
	static uint16_t DataBitReceiveIndex;	//接前接收位的位置


    //清除状态
    if(HCS301_DecodeStep == 0)
    {
        CurrentTimeValue = GET_TIMERCOUNT();
        LastTimeValue = GET_TIMERCOUNT();
        HCS301_DecodeStep++;
        PwmCount = 0;
    }

    //检测TP跟TH信号
    else if(HCS301_DecodeStep == 1)
    {
        CurrentTimeValue = GET_TIMERCOUNT();
        DetaTimeValue = CurrentTimeValue - LastTimeValue;
        LastTimeValue = CurrentTimeValue;
        
        //TP PWM信号
        if(DetaTimeValue > 260 && DetaTimeValue < 660)
        {
            PwmCount++;
        }
        //TG 信号
        else if(DetaTimeValue > 260*10 && DetaTimeValue < 660*10)
        {
            //实际TP 信号有23个脉冲
            if(DetaTimeValue > 20)
            {
                HCS301_DecodeStep++;
                DataBitReceiveIndex = 0;
            }
            else
            {
                goto error;
            }
        }
        else
        {
            goto error;
        }
    }
    //接收数据部分
    else if(HCS301_DecodeStep == 2)
    {
        DataBitReceiveIndex++;
        CurrentTimeValue = GET_TIMERCOUNT();
        DetaTimeValue = CurrentTimeValue - LastTimeValue;
        LastTimeValue = CurrentTimeValue;

        //通过时间来判断逻辑1或0
        if(DataBitReceiveIndex%2 == 0)
        {
            //记录位
            if(DetaTimeValue > (520) && DetaTimeValue < (1320))
            {
                WriteBit((DataBitReceiveIndex / 2) - 1 , 0x01);
            }
            else if(DetaTimeValue > (260) && DetaTimeValue < (660))
            {
                WriteBit((DataBitReceiveIndex / 2) -1 , 0x00);
            }
            else
            {
                //err;
                goto error;
            }

            //接收完成退出
            if(DataBitReceiveIndex == 128)
            {
                //解密
                Test_DECRYPT(EncryPortion);

                //判断识别码值是否跟我烧录时候相同
                if((EncryPortion_de & 0x03FF0000) == 0x01370000)
                {
                    Sync_Current = EncryPortion_de;
                    //两次同步值要不同才认为是新的按键按下
                    if(Sync_Last != Sync_Current)
                    {
                        FixedPortion_de = FixedPortion;
                        gHcs301Code1 = FixedPortion_de;
                        gHcs301Code2 = EncryPortion_de;
                        IsSendCodeToPc = 1;
                    }
                    
                    Sync_Last = Sync_Current;
                }
                goto error;
            }
        }
    }
		
	return;

error:
	//出错
	WakeupEnable = 1;
	HCS301_DecodeStep = 0;
	xBSP_HCS301_IoInput();
}



uint16_t LowTimeCount = 0;		//连续低电平计数
uint16_t LowTimeCountMax = 0;	//连续低电平计数最大值
uint8_t LastPinStatus = 0;      //上次电平值
uint8_t CurrentPinStatus = 0;   //当前电平值





void RFMODLE_CheckStart(void)
{
    //接收数据时，检测停止
	if(WakeupEnable == 0)
	{
		return;
	}

	CurrentPinStatus = xBSP_HCS301_GetPIn();

    //连续低电平累加
	if((LastPinStatus == CurrentPinStatus) && CurrentPinStatus == 0x00)
	{
		LowTimeCount++;
		if(LowTimeCountMax < LowTimeCount)
		{
			LowTimeCountMax = LowTimeCount;
		}
	}
	else
	{
		LowTimeCount = 0;

		//判断低电平脉冲是否符合TG
		if(LowTimeCountMax > 100 && LowTimeCountMax <257)
		{
            //启动接收数据
			WakeupEnable = 0;
			xBSP_HCS301_IoInt();
            
		}
        LowTimeCountMax = 0;
	}

	LastPinStatus = CurrentPinStatus;
}

/*
*********************************************************************************************************************

@ Brief  : 写接收数据的数据位

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-03 18:57

*********************************************************************************************************************
*/
void WriteBit(uint8_t bit , uint8_t value)
{
	if(bit < 32)
	{
		if(value)
		{
			EncryPortion |=  (0x01 << bit);
		}
		else
		{
			EncryPortion &=  ~(0x01 << bit);
		}
	}
	else if(bit < 64)
	{
		bit -= 32;
		if(value)
		{
			FixedPortion |=  (0x01 << bit);
		}
		else
		{
			FixedPortion &=  ~(0x01 << bit);
		}
	}
	else
	{
		
	}
}



/*************************************************************************************************************************/
//以下是加密跟解密相关的函数了。

unsigned char NLF[2][2][2][2][2];

void init()
{
    NLF[0][0][0][0][0]=0;
    NLF[0][0][0][0][1]=1;
    NLF[0][0][0][1][0]=1;
    NLF[0][0][0][1][1]=1;
    NLF[0][0][1][0][0]=0;
    NLF[0][0][1][0][1]=1;
    NLF[0][0][1][1][0]=0;
    NLF[0][0][1][1][1]=0;
    
    NLF[0][1][0][0][0]=0;
    NLF[0][1][0][0][1]=0;
    NLF[0][1][0][1][0]=1;
    NLF[0][1][0][1][1]=0;
    NLF[0][1][1][0][0]=1;
    NLF[0][1][1][0][1]=1;
    NLF[0][1][1][1][0]=1;
    NLF[0][1][1][1][1]=0;
    
    NLF[1][0][0][0][0]=0;
    NLF[1][0][0][0][1]=0;
    NLF[1][0][0][1][0]=1;
    NLF[1][0][0][1][1]=1;
    NLF[1][0][1][0][0]=1;
    NLF[1][0][1][0][1]=0;
    NLF[1][0][1][1][0]=1;
    NLF[1][0][1][1][1]=0;
    
    NLF[1][1][0][0][0]=0;
    NLF[1][1][0][0][1]=1;
    NLF[1][1][0][1][0]=0;
    NLF[1][1][0][1][1]=1;
    NLF[1][1][1][0][0]=1;
    NLF[1][1][1][0][1]=1;
    NLF[1][1][1][1][0]=0;
    NLF[1][1][1][1][1]=0;
}

//获取source第n个位数
unsigned char getBit(unsigned char source[],int n)
{
    unsigned char temp0=(unsigned char)1<<(n%8);
    unsigned char temp1=source[n/8]&temp0;
    if(temp1!=0)
    {
        return 1;
    }
    return 0;
}

//source带进位右移
unsigned char * RRC(unsigned char source[],char c,char n)
{
    int i=0;
    unsigned char temp;
    for(i=n-1;i>=0;i--)
    {
        temp=source[i];
        if(c!=0){
            source[i]=(source[i]>>1)|0x80;
        }else{
            source[i]=(source[i]>>1)&0x7f;
        }
        
        if((temp&0x01) != 0){
            c=1;
        }else{
            c=0;
        }
    }
    return source;
}

//source带进位左移
unsigned char * RLC(unsigned char source[],char c,char n)
{
    int i=0;
    unsigned char temp;
    for(i=0;i<n;i++)
    {
        temp=source[i];
        if(c!=0){
            source[i]=(source[i]<<1)|0x01;
        }else{
            source[i]=(source[i]<<1)&0xfe;
        }
        
        if((temp&0x80)!=0){
            c=1;
        }else{
            c=0;
        }
    }
    return source;
}

//加密
unsigned char* CRYPT(unsigned char *source,unsigned char key[])
{
    int i=0;
    unsigned char c=0;
    unsigned char nlf,y16,y0,k,result;
    init();
    for (i = 0; i < 528; i++)
    {
        nlf=NLF[getBit(source, 31)][getBit(source, 26)][getBit(source, 20)][getBit(source, 9)][getBit(source, 1)];
        y16=getBit(source, 16);
        y0=getBit(source, 0);
        k=getBit(key, i%64);
        result=nlf^y16^y0^k;
        if (result!=0) 
		{
            c=1;
        }
		else 
		{
            c=0;
        }
        source=RRC(source,c,4);
    }
    return source;
}

//解密
unsigned char*  DECRYPT(unsigned char *source,unsigned char key[])
{
    int i=0;
    unsigned char c=0;
    unsigned char nlf,y15,y31,k,result;
    init();
    for (i = 528; i >0; i--)
    {
        nlf=NLF[getBit(source, 30)][getBit(source, 25)][getBit(source, 19)][getBit(source, 8)][getBit(source, 0)];
        y15=getBit(source, 15);
        y31=getBit(source, 31);
        k=getBit(key, (i-1)%64);
        result=nlf^y15^y31^k;
        if ( result != 0)
		{
			c=1;
		}      
        else
		{
			c=0;
		}                 
        source=RLC(source,c,4);
    }
    return source;
}





/*
*********************************************************************************************************************

@ Brief  : 解密数据

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-29 17:23

*********************************************************************************************************************
*/
void Test_DECRYPT(uint32_t data)
{
    source[0]=(unsigned char)(data);
    source[1]=(unsigned char)(data>>8);
    source[2]=(unsigned char)(data>>16);
    source[3]=(unsigned char)(data>>24);

	//解密
    DECRYPT(source, HCS301_Decryptkey);

    EncryPortion_de = source[3];
    EncryPortion_de <<= 8;
    EncryPortion_de |= source[2];
    EncryPortion_de <<= 8;
    EncryPortion_de |= source[1];
    EncryPortion_de <<= 8;
    EncryPortion_de |= source[0];
}


/**************************************************END OF FILE*******************************************************/
